package com.getpebble.android.framework.protocol.outbound;

import com.getpebble.android.common.version.AndroidPebbleAppVersion;
import com.getpebble.android.framework.protocol.EndpointId;
import com.getpebble.android.framework.util.ByteUtils;
import com.google.common.primitives.UnsignedInteger;
import java.util.ArrayList;
import java.util.List;

public class PblOutboundPhoneVersionMessage extends PblOutboundMessage {
    private static final OperatingSystem mOperatingSystem = OperatingSystem.ANDROID;
    private AndroidPebbleAppVersion mAppVersion;
    private final List<RemoteCapability> mRemoteCapabilities = new ArrayList();
    private final List<SessionCapability> mSessionCapabilities = new ArrayList();

    public enum OperatingSystem {
        UNKNOWN(0),
        IOS(1),
        ANDROID(2),
        OSX(3),
        LINUX(4),
        WINDOWS(5);
        
        private final int id;

        private OperatingSystem(int id) {
            this.id = id;
        }

        public int getId() {
            return this.id;
        }
    }

    public enum RemoteCapability {
        TELEPHONY(16),
        SMS(32),
        GPS(64),
        BTLE(128),
        CAMERA_FRONT(240),
        CAMERA_REAR(256),
        ACCEL(512),
        GYRO(1024),
        COMPASS(2048);
        
        private final int id;

        private RemoteCapability(int id) {
            this.id = id;
        }

        public int getId() {
            return this.id;
        }
    }

    public enum SessionCapability {
        GEOLOCATION(1),
        GAMMA_RAY(Integer.MIN_VALUE);
        
        private final int id;

        private SessionCapability(int id) {
            this.id = id;
        }

        public int getId() {
            return this.id;
        }
    }

    public PblOutboundPhoneVersionMessage(AndroidPebbleAppVersion appVersion) {
        super(EndpointId.PHONE_VERSION);
        this.mAppVersion = appVersion;
    }

    private final UnsignedInteger getRemoteBitField() {
        int result = 0 | mOperatingSystem.getId();
        for (RemoteCapability c : this.mRemoteCapabilities) {
            result |= c.getId();
        }
        return UnsignedInteger.fromIntBits(result);
    }

    private final UnsignedInteger getSessionBitField() {
        int result = 0;
        for (SessionCapability c : this.mSessionCapabilities) {
            result |= c.getId();
        }
        return UnsignedInteger.fromIntBits(result);
    }

    public byte[] getBytes() {
        if (!areBytesCached()) {
            addBytes(Byte.valueOf((byte) 1));
            addBytes(ByteUtils.unsignedInt2bytes(UnsignedInteger.MAX_VALUE));
            addBytes(ByteUtils.unsignedInt2bytes(getSessionBitField()));
            addBytes(ByteUtils.unsignedInt2bytes(getRemoteBitField()));
            addBytes(Byte.valueOf((byte) 2));
            addBytes(Byte.valueOf((byte) this.mAppVersion.getMajor()));
            addBytes(Byte.valueOf((byte) this.mAppVersion.getMinor()));
            addBytes(Byte.valueOf((byte) this.mAppVersion.getPoint()));
        }
        return super.getBytes();
    }
}
